#include <iostream>

using std::cout;
using std::endl;

class Point
{
public:
    Point(int ix = 0, int iy = 0)
    : _ix(ix)
    , _iy(iy )
    {
        cout << "Point(int = 0, int = 0)" << endl;
    }

    void print() const
    {
        cout << "(" << _ix 
             << ", " << _iy
             << ")" << endl;
    }

    ~Point()
    {
        cout << "~Point()" << endl;
    }

private:
    int _ix;
    int _iy;
};

template <typename T>
class RAII
{
public:
    //1、在构造函数中初始化资源(资源是new出来)
    RAII(T *pdata)
    : _pdata(pdata)
    {
        cout << "RAII(T *)" << endl;
    }

    //2、在析构函数中释放资源
    ~RAII()
    {
        cout << "~RAII()" << endl;
        if(_pdata)
        {
            delete _pdata;
            _pdata = nullptr;
        }
    }
    //3、提供若干访问资源的方法
    T *get() const
    {
        return _pdata;
    }

    T *operator->()
    {
        return _pdata;
    }

    T operator*()
    {
        return *_pdata;
    }

    void reset(int *pdata)
    {
        if(_pdata)
        {
            delete _pdata;
            _pdata = nullptr;
        }
        _pdata = pdata;
    }

    //4、不允许复制或者赋值
    RAII(const RAII &rhs) = delete;
    RAII &operator=(const RAII &rhs) = delete;
private:
    T *_pdata;
};

int main(int argc, char *argv[])
{
    //raii在此处是一个栈对象，但是因为重载了->与*，使用起来
    //类似与一个指针，但是比普通指针更加智能，直管堆空间的
    //创建，不用管堆空间的销毁(raii有智能指针的雏形)
    RAII<Point> raii(new Point(10, 20));//raii栈对象
    raii->print();
    (*raii).print();
    /* raii.operator->()->print(); */
    /* RAII<int> raii2(new int(10)); */
    /* RAII<double> raii3(new double(10)); */
    return 0;
}

